<?php

namespace App\Http\Controllers\Common;

use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Common\Attachment;
use App\Helpers\Code;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Storage;

//use Symfony\Component\HttpFoundation\BinaryFileResponse;

class AttachmentController extends Controller
{

    private $fields = [
        'attachment', 'ethics_materials', 'symptom_checklist',
        'depression_scale', 'anxiety_scale', 'atigue_evaluation', 'sleep_evaluation', 'adapt_evaluation',
        'radiographic_file', 'electrocardiogram_file', 'informed_consent', 'case_file', 'attachment_file',
        'logistics_attachment', 'logistics_bill_attachment'
    ];
    private $tables = [
        'attachment' => ['projects', '\App\Models\Project\Project'],
        'ethics_materials' => ['project_map_organization', '\App\Models\Project\ProjectMapOrganization'],
        'symptom_checklist' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'depression_scale' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'anxiety_scale' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'atigue_evaluation' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'sleep_evaluation' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'adapt_evaluation' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'radiographic_file' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'electrocardiogram_file' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'informed_consent' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'case_file' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'attachment_file' => ['patient_cases', '\App\Models\Patient\PatientCase'],
        'logistics_attachment' => ['logisticss', '\App\Models\Logistics\Logistics'],
        'logistics_bill_attachment' => ['logisticss', '\App\Models\Logistics\Logistics'],
    ];
    /* 包含项目附件，病历附件以及咨询附件 */
    private $uploadPath = 'uploads';
    /* 可见即可得编辑器附件 */
    private $uploadPublicPath = 'files';
    /* 所有widget附件 */
    private $uploadWidgetPath = 'files';

    public function __construct()
    {
        $this->rules = [
            'files' => 'bail|required',
            'from_id' => 'bail|required|integer',
            'from_field' => ['bail', 'required', Rule::in($this->fields)]
        ];

        $this->messages = [
            'files.required' => trans('system.file.files_required'),
            'from_id.required' => trans('system.file.from_id_required'),
            'from_id.integer' => trans('system.file.from_id_integer'),
            'from_field.required' => trans('system.file.from_field_required'),
            'from_field.in' => trans('system.file.from_field_in'),
        ];

        $this->model = new Attachment();
    }

    public function addAttachment(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), $this->rules, $this->messages);

            if ($validator->fails()) {
                return $this->error($validator, Code::SYSTEM_VALIDATOR_ERROR);
            }

            $from_id = $request->input('from_id');
            $from_field = $request->input('from_field');
            $files = $request->file('files');
            $model = new $this->tables[$from_field][1]();

            $checkValidate = $this->checkValidate($request->all(), $from_id, $files, $model);
            if (!empty($checkValidate)) {
                return $checkValidate;
            }

            $data = [];
            foreach ($files as $key => $value) {
                $raw_name = Storage::putFile($this->uploadPath, $value);

                $store_name = substr($raw_name, strlen($this->uploadPath) + 1);

                $item['original_name'] = $value->getClientOriginalName();
                $item['store_name'] = substr($store_name, 0, strpos($store_name, '.'));
                //            $item['extension'] = $value->getClientOriginalExtension();
                $item['extension'] = substr($store_name, strpos($store_name, '.') + 1);
                $item['size'] = $value->getSize();
                $item['mime_type'] = $value->getMimeType();
                $item['type'] = $value->getType();

                $item['from_field'] = $from_field;
                $item['from_id'] = $from_id;
                $item['from_table'] = $this->tables[$from_field][0];
                $data[] = $item;
            }

            $results = $this->model->addAttachment($data);

            $payload = [];
            $payload['from_id'] = $from_id;
            $payload['from_field'] = $from_field;

            foreach ($results as $value) {
                $payload['items'][] = $value->id;
            }

            $model->uploadAttachment($payload);

            $this->result['data'] = $results;
            return $this->result;
        } catch (\Exception $e) {
            return $this->throwError($e);
        }
    }

    public function getAttachment($filename)
    {
        try {
            $model = $this->model->isExist($filename);

            if (!$model) {
                return $this->error('common.get_failure');
            }

            return Storage::download($this->uploadPath . '/' . $filename . '.' . $model->extension);
        } catch (\Exception $e) {
            return $this->throwError($e);
        }

//        $file = file_get_contents(storage_path() . '/app/' . $this->uploadPath . '/' . $filename . '.' . $model->extension);
//
//        header('Content-type: ' . $model->mime_type . ';');
//        header("Content-Length: " . strlen($file));
//        echo $file;
    }

    public function getWidgetAttachment($filename)
    {
        try {
            $model = $this->model->isExist($filename);

            if (!$model) {
                return $this->error('common.get_failure');
            }

            return Storage::download($this->uploadWidgetPath . '/' . $filename . '.' . $model->extension);
        } catch (\Exception $e) {
            return $this->throwError($e);
        }
    }

    public function deleteAttachment($filename, Request $request)
    {
        try {
            $rules = [
                'from_id' => 'bail|required|integer',
                'from_field' => ['bail', 'required', Rule::in($this->fields)]
            ];

            $validator = Validator::make($request->all(), $rules, $this->messages);

            if ($validator->fails()) {
                return $this->error($validator, Code::SYSTEM_VALIDATOR_ERROR);
            }

            $from_id = $request->input('from_id');
            $from_field = $request->input('from_field');

            $model = new $this->tables[$from_field][1]();

            if (!$model->isExist($from_id)) {
                return $this->error('common.recored_not_found');
            }

            $data['store_name'] = $filename;

            $result = $this->model->deleteAttachment($data);

            if (!$result) {
                return $this->error('common.delete_failure');
            }

            $payload = [];
            $payload['from_id'] = $from_id;
            $payload['from_field'] = $from_field;

            $payload['item'] = $result;

            $model->deleteAttachment($payload);

            return $this->result;
        } catch (\Exception $e) {
            return $this->throwError($e);
        }
    }

    /**
     * 公共文件上传
     * @param Request $request
     * @return array
     */
    public function addCommonAttachment(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), $this->rules, $this->messages);

            if ($validator->fails()) {
                return $this->error($validator, Code::SYSTEM_VALIDATOR_ERROR);
            }

            return $this->uploadCommonSection($request->all(), $request->input('from_id'), $request->input('from_field'), $request->file('files'));
        } catch (\Exception $e) {
            return $this->throwError($e);
        }
    }

    public function uploadCommonSection($info, $from_id, $from_field, $files)
    {
        try {
            $model = new $this->tables[$from_field][1]();
            $check = $this->checkValidate($info, $from_id, $files, $model);
            if (!empty($check)) {
                return $check;
            }

            $data = [];
            foreach ($files as $key => $value) {
                $item['original_name'] = $value->getClientOriginalName();
                $item['store_name'] = md5(time() . $item['original_name']);
                $item['extension'] = $value->getClientOriginalExtension();
                //            $item['extension'] = substr($store_name, strpos($store_name, '.') + 1);
                $item['size'] = $value->getSize();
                $item['mime_type'] = $value->getMimeType();
                $item['type'] = $value->getType();

                $item['from_field'] = $from_field;
                $item['from_id'] = $from_id;
                $item['from_table'] = $this->tables[$from_field][0];
                $value->move(public_path($this->uploadPublicPath), $item['store_name'] . '.' . $item['extension']);
                $data[] = $item;
            }

            $results = $this->model->addAttachment($data);

            $payload = [];
            $payload['from_id'] = $from_id;
            $payload['from_field'] = $from_field;

            foreach ($results as $value) {
                $payload['items'][] = $value->id;
            }

            $model->uploadAttachment($payload);

            $this->result['data'] = array_reduce(json_decode(json_encode($results), true), function ($resUrl, $v) {
                $v['url'] = asset($this->uploadPublicPath) . '/' . $v['store_name'] . '.' . $v['extension'];
                $resUrl = $v;
                return $resUrl;
            });

            return $this->result;
        } catch (\Exception $e) {
            return $this->throwError($e);
        }
    }

    public function checkValidate($info, $from_id, $files, $model)
    {
        try {
            if (!$model->isExist($from_id)) {
                return $this->error('common.recored_not_found');
            }

            foreach ($files as $key => $value) {
                $rules['files.' . $key] = 'bail|required|mimes:jpeg,gif,png,pdf,doc,docx,xls,xlsx,ppt,pptx|max:10240';
                $messages['files.' . $key . '.mimes'] = trans('system.file.files_mimes');
                $messages['files.' . $key . '.max'] = trans('system.file.files_max');
            }
            $validatorFiles = Validator::make($info, $rules, $messages);

            if ($validatorFiles->fails()) {
                return $this->error($validatorFiles, Code::SYSTEM_VALIDATOR_ERROR);
            }
        } catch (\Exception $e) {
            return $this->throwError($e);
        }
    }

}
